#include <jni.h>
#include <string>
#include <android/log.h> // Android日志头文件

#include "JNIStringAutoRelease.cpp"

// 日志宏定义（最佳实践：统一日志标签和格式）
#define LOG_TAG "JNI_PRACTICE"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

// 凯撒密码加密函数
std::string caesarCipherEncrypt(const std::string& text, int shift) {
    std::string result = "";

    // 处理负数偏移
    shift = shift % 26;
    if (shift < 0) {
        shift += 26;
    }

    for (char c : text) {
        if (isalpha(c)) {
            // 处理大写字母
            if (isupper(c)) {
                result += char((c - 'A' + shift) % 26 + 'A');
            }
                // 处理小写字母
            else {
                result += char((c - 'a' + shift) % 26 + 'a');
            }
        } else {
            // 非字母字符保持不变
            result += c;
        }
    }

    return result;
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_pmt_jnipractice_NativeUtils_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++ Jni result";
    LOGD("stringFromJNI called with a=%s", hello.c_str());
    return env->NewStringUTF(hello.c_str());
}

/**
 * 字符串处理（C层拼接字符串）
 * 最佳实践：使用GetStringUTFChars获取C字符串，使用后必须Release释放
 * @param env
 * @param this
 * @param str1
 * @param str2
 * @return
 */
extern "C" JNIEXPORT jstring JNICALL
Java_com_pmt_jnipractice_NativeUtils_concatStrings(
        JNIEnv* env,
        jobject /* this */,
        jstring str1,
        jstring str2) {
    // 检查输入是否为null（最佳实践：防御性编程）
    if (str1 == nullptr || str2 == nullptr) {
        LOGE("concatStrings: str1 or str2 is null");
        return env->NewStringUTF(""); // 返回空字符串而非null，避免Java层NPE
    }
    JNIStringAutoRelease cstr1(env, str1);
    JNIStringAutoRelease cstr2(env, str2);
    if(cstr1.get() == nullptr || cstr2.get() == nullptr) {
        LOGE("concatStrings: str1 or str2 is null");
        LOGE("GetStringUTFChars failed (OOM?)");
        // 释放已获取的引用（避免内存泄漏）
        if (cstr1.get() != nullptr) env->ReleaseStringUTFChars(str1, cstr1.get());
        if (cstr2.get() != nullptr) env->ReleaseStringUTFChars(str2, cstr2.get());
        return env->NewStringUTF("");
    }
    std::string concat_str = std::string(cstr1.get()) + std::string(cstr2.get());
    return env->NewStringUTF(concat_str.c_str());
    /*
    // 1. 将jstring转换为C字符串（使用GetStringUTFChars，会申请内存）
    // isCopy：是否为原字符串的拷贝（通常忽略，只需确保释放）
    const char* c_str1 = env->GetStringUTFChars(str1, nullptr);
    const char* c_str2 = env->GetStringUTFChars(str2, nullptr);
    if (c_str1 == nullptr || c_str2 == nullptr) {
        LOGE("GetStringUTFChars failed (OOM?)");
        // 释放已获取的引用（避免内存泄漏）
        if (c_str1 != nullptr) env->ReleaseStringUTFChars(str1, c_str1);
        if (c_str2 != nullptr) env->ReleaseStringUTFChars(str2, c_str2);
        return env->NewStringUTF("");
    }
    // 2. 拼接C字符串
    std::string concat_str = std::string(c_str1) + std::string(c_str2);

    // 3. 释放C字符串内存（必须！否则内存泄漏）
    env->ReleaseStringUTFChars(str1, c_str1);
    env->ReleaseStringUTFChars(str2, c_str2);

    // 4. 将C字符串转换为jstring返回
    return env->NewStringUTF(concat_str.c_str());
     */
}

/**
 * 字符串加密功能 - 凯撒密码
 * @param env JNI环境
 * @param thiz 对象实例
 * @param input 待加密字符串
 * @param shift 偏移量
 * @return 加密后的字符串
 */
extern "C" JNIEXPORT jstring JNICALL
Java_com_pmt_jnipractice_NativeUtils_encryptString(
        JNIEnv* env,
        jobject /* thiz */,
        jstring input,
        jint shift) {

    // 检查输入是否为null
    if (input == nullptr) {
        LOGE("encryptString: input is null");
        return env->NewStringUTF("");
    }

    // 使用自动释放类获取C字符串
    JNIStringAutoRelease cstr(env, input);
    if (cstr.get() == nullptr) {
        LOGE("encryptString: failed to get C string");
        return env->NewStringUTF("");
    }

    // 执行加密
    std::string encrypted = caesarCipherEncrypt(std::string(cstr.get()), shift);

    // 返回加密结果
    return env->NewStringUTF(encrypted.c_str());
}
